package com.db;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.bson.types.ObjectId;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.QueryOperators;
import com.util.SystemProperty;

public class MongoDBConn {
	
	private static MongoDBConn instance ;
	private DB db ;
	private Mongo mg ;
	
	public MongoDBConn(){
		try {
			String host = SystemProperty.getInstance("parameterConfig").getProperty("mongodb_url") ;
			int port = Integer.parseInt(SystemProperty.getInstance("parameterConfig").getProperty("mongodb_post")) ;
			String dbname = SystemProperty.getInstance("parameterConfig").getProperty("mongodb_dbname") ;
			mg = new Mongo(host, port) ;
			db = mg.getDB(dbname) ;
		} catch (Exception e) {
			e.printStackTrace() ;
		}
	}
	
	public static synchronized MongoDBConn getInstance(){
		if(instance == null) {
			instance = new MongoDBConn();
		}
		return instance ;
	}
	
	/**
	 * 插入数据
	 * @param collectionName
	 * @param dbObject
	 * @return
	 */
	public int insert(String collectionName, DBObject dbObject){
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.save(dbObject).getN();
	}
	
	/**
	 * 查询单条记录
	 * @param collectionName
	 * @param dbObject
	 * @return
	 */
	public DBObject findOne(String collectionName, DBObject query) {
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.findOne(query);
	}
	
	/**
	 * 查询所有数据
	 * @param collectionName
	 * @return
	 */
	public List<DBObject> queryAll(String collectionName) {
		DBCollection dbCollection = db.getCollection(collectionName) ;
	    DBCursor cur = dbCollection.find();
	    List<DBObject> list = cur.toArray() ;
	    return list ;
	}
	
	/**
	 * 查询
	 * @param collectionName
	 * @param dbObject
	 * @return
	 */
	public List<DBObject> findByDBObject(String collectionName, DBObject dbObject, int page, int size) {
		DBCollection dbCollection = db.getCollection(collectionName) ;
		
		page = page == 0 ? 1 : page ; 
		int skip = (page - 1) * size ;
		dbCollection.find(dbObject).size() ;
		return dbCollection.find(dbObject).skip(skip).limit(size).toArray() ;
	}
	
	/**
	 * 查询总记录数
	 * @param collectionName
	 * @param dbObject
	 * @return
	 */
	public int findByDBObjectCount(String collectionName, DBObject dbObject) {
		DBCollection dbCollection = db.getCollection(collectionName) ;
		
		return dbCollection.find(dbObject).size() ;
	}
	
	/**
	 * 修改数据，单条数据
	 * @param collectionName
	 * @param _id
	 * @param dbObject 需要修改的文档
	 * @param upsert 如果数据库不存在，是否添加
	 * @param multi 多条修改 false只修改第一天，true如果有多条就不修改
	 * @return
	 */
	public int modify(String collectionName,String _id, DBObject dbObject, boolean upsert, boolean multi) {
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.update(new BasicDBObject("_id", new ObjectId(_id)), dbObject, upsert, multi).getN() ;
	}
	
	/**
	 * 修改多条数据
	 * @param collectionName
	 * @param query	查询文档
	 * @param obj	修改文档
	 * @return
	 */
	public int modifyMore(String collectionName, DBObject query, DBObject obj){
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.updateMulti(query, query).getN() ;
	}
	
	/**
	 * 
	 * @param collectionName 修改文档名称
	 * @param dbObject1	修改的查询条件
	 * @param dbObject2	修改内容
	 * @param dbObject3	修改的属性
	 * @param upsert	如果数据库不存在，是否添加
	 * @param multi		多条修改 false只修改第一天，true如果有多条就不修改
	 * @return
	 */
	public DBObject findAndModify(String collectionName,DBObject dbObject1, DBObject dbObject2, DBObject dbObject3, boolean upsert, boolean multi){
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.findAndModify(dbObject1, 
			dbObject3, 
			new BasicDBObject("addres", true), //修改值的属性，可以为null
			false, 	//是否删除，true表示删除
			dbObject2, 	//修改的值
			upsert,	//如果数据库不存在，是否添加
			multi	//多条修改 false只修改第一天，true如果有多条就不修改
		) ;	
	}
	
	/**
	 * 删除数据
	 * @param collectionName
	 * @param dbObject
	 * @return
	 */
	public int remove(String collectionName,DBObject dbObject){
		DBCollection dbCollection = db.getCollection(collectionName) ;
		return dbCollection.remove(dbObject).getN();		
	}
	
	public DB getDb() {
		return db;
	}

	public void setDb(DB db) {
		this.db = db;
	}

	public Mongo getMg() {
		return mg;
	}

	public void setMg(Mongo mg) {
		this.mg = mg;
	}
	
	public static void main(String[] args) {
		MongoDBConn dbConn = MongoDBConn.getInstance() ;
//		for (String name : dbConn.getMg().getDatabaseNames()) {
//            System.out.println("dbName: " + name);
//        }
//		
//		//查询所有的聚集集合
//        for (String name : dbConn.getDb().getCollectionNames()) {
//            System.out.println("collectionName: " + name);
//        }
        String collectionName = "sys_user" ;
        
		DBObject test = new BasicDBObject();
		//test.put("id", 2) ;
		//test.put("name", "two") ;
		test.put("addres", "上海") ;
		//test.put("phone", "13800138002") ;
		
		BasicDBObject test2 = new BasicDBObject();
//		test2.put("_id", new ObjectId("507fc690761cb09550868b56")) ;
		test2.put("id", new BasicDBObject("$gte", 95)) ;
		
//		dbConn.insert(collectionName, test) ;
//		System.out.println(dbConn.modify(collectionName, "507fb976761c369b1b82426d", test, true, false));
//		System.out.println(dbConn.findAndModify(collectionName, test2, test, new BasicDBObject("addres", true), false, true));
//		
//		
//		System.out.println(dbConn.remove(collectionName, test2));
		
		List<DBObject> list = dbConn.queryAll(collectionName) ;
		
		
		test = new BasicDBObject();
		test.put("id", new BasicDBObject("$gte", 0)) ;
//		test.put("phone", new BasicDBObject("$lte", "138001380033")) ;
		list = dbConn.findByDBObject(collectionName, test, 10, 10) ;
		
		for(DBObject object : list) {
			Iterator iter = object.toMap().entrySet().iterator();
			while (iter.hasNext()) {
				Map.Entry entry = (Map.Entry) iter.next();
				Object key = entry.getKey();
				Object val = entry.getValue();
				System.out.print(key + ":" + val + ", ");
			}
			System.out.println();
		}
	}
}
